#include <cstdio>
using namespace std;
const int N = 1000010;
int n, m, root[N];
struct Segment {
	int data, ls, rs;
} tree[50 * N];
int tot;
int a[N];
int build(int l, int r) {
	int p = ++tot;
	if (l == r) {
		tree[p].data = a[l];
		return p;
	}
	int mid = (l + r) >> 1;
	tree[p].ls = build(l, mid);
	tree[p].rs = build(mid + 1, r);
	return p;
}

int modify(int cur, int pos, int l, int r, int val) {
	int p = ++tot;
	tree[p] = tree[cur];
	if (l == r) {
		tree[p].data = val;
		return p;
	}
	int mid = (l + r) >> 1;
	if (pos <= mid) {
		tree[p].ls = modify(tree[cur].ls, pos, l, mid, val);
	} else {
		tree[p].rs = modify(tree[cur].rs, pos, mid + 1, r, val);
	}
	return p;
}

int query(int cur, int pos, int l, int r) {
	if (l == r) return tree[cur].data;
	int mid = (l + r) >> 1;
	if (pos <= mid)
		return query(tree[cur].ls, pos, l, mid);
	else
		return query(tree[cur].rs, pos, mid + 1, r);
}
int main() {
	// freopen("testdata.in", "r", stdin);
	// freopen("testdata.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
	}
	root[0] = build(1, n);
	int ro, type, loc, vl;
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d", &ro, &type);
		switch (type) {
		case 1:
			scanf("%d%d", &loc, &vl);
			root[i] = modify(root[ro], loc, 1, n, vl);
			break;
		case 2:
			scanf("%d", &loc);
			printf("%d\n", query(root[ro], loc, 1, n));
			root[i] = root[ro];
			break;
		}
	}
	return 0;
}